﻿using System;
using System.Linq.Expressions;
using FluentExport.CSVExport;
using FluentExport.CSVExport.Interfaces;
using NSubstitute;
using NUnit.Framework;
using Should.Fluent;
using System.Collections.Generic;

namespace FluentExport.Tests.CSVExportTests
{
    [TestFixture]
    public class CSVExportTests
    {
        [Test]
        public void MustInvokeWhenIsCorrectly()
        {
            var sCsvExportHelper = Substitute.For<ICSVExportHelper>();

            var csvExport = new CSVExport.CSVExport(sCsvExportHelper);

            var ret = csvExport.CreateSource<DummyClassTest>(d => d.Id);

            ret.Should().Not.Be.Null();
        }

        [Test]
        public void MustTryInvokeWhenIsAndGetArgumentException()
        {
            var sCsvExportHelper = Substitute.For<ICSVExportHelper>();

            var csvExport = new CSVExport.CSVExport(sCsvExportHelper);

            Expression<Func<DummyClassTest, object>> expression = null;

            var ex = Assert.Throws<ArgumentException>(() => csvExport.CreateSource(expression));

            ex.Should().Not.Be.Null();
            ex.Message.Should().Equal("The mapping expression can not be null.");
        }

        [Test]
        public void MustInvokeWhenIsWithAListOfExpressionCorrectly()
        {
            var sCsvExportHelper = Substitute.For<ICSVExportHelper>();

            var csvExport = new CSVExport.CSVExport(sCsvExportHelper);

            var ret = csvExport.CreateSource<DummyClassTest>(d => d.Id, d => d.Name);

            ret.Should().Not.Be.Null();
        }

        [Test]
        public void MustInvokeWhenIsForCompoundRuleCorrectly()
        {
            var sCsvExportHelper = Substitute.For<ICSVExportHelper>();

            var csvExport = new CSVExport.CSVExport(sCsvExportHelper);

            var ret = csvExport.CreateCompoundSource<DummyClassTest>();

            ret.Should().Not.Be.Null();
            ret.Should().Be.OfType(typeof(CSVCompoundSource<DummyClassTest>));
        }

        [Test]
        public void MustAddHeaderCorrectly()
        {
            var sCsvExportHelper = Substitute.For<ICSVExportHelper>();

            var csvExport = new CSVExport.CSVExport(sCsvExportHelper);

            var ret = csvExport.Header("Test");

            ret.Should().Not.Be.Null();
            ret.Should().Be.OfType(typeof(CSVExport.CSVExport));
        }

        [Test]
        public void MustAddHeadersCorrectly()
        {
            var sCsvExportHelper = Substitute.For<ICSVExportHelper>();

            var csvExport = new CSVExport.CSVExport(sCsvExportHelper);

            var ret = csvExport.Headers("Test", "Test1");

            ret.Should().Not.Be.Null();
            ret.Should().Be.OfType(typeof(CSVExport.CSVExport));
        }

        [Test]
        public void MustExportObjectToCSVCorrectly()
        {
            var sCsvExportHelper = Substitute.For<ICSVExportHelper>();
            sCsvExportHelper.FormatValue(Arg.Any<object>()).Returns(x => x[0].ToString());
            sCsvExportHelper.GetPropertyName(Arg.Any<Expression<Func<DummyClassTest, object>>>()).Returns("Id");

            var csvExport = new CSVExport.CSVExport(sCsvExportHelper);
            csvExport.CreateSource<DummyClassTest>(d => d.Id);

            var data = new DummyClassTest { Id = 222 };

            var csv = csvExport.Export(data);

            csv.Should().Not.Be.Null();
            csv.Result.Should().Not.Be.Null();
            csv.ToString().Should().Equal("222,\r\n");
        }

        [Test]
        public void MustExportCollectionToCSVCorrectly()
        {
            var sCsvExportHelper = Substitute.For<ICSVExportHelper>();
            sCsvExportHelper.FormatValue(Arg.Any<object>()).Returns(x => x[0].ToString());
            sCsvExportHelper.GetPropertyName(Arg.Any<Expression<Func<DummyClassTest, object>>>()).Returns("Name");

            var csvExport = new CSVExport.CSVExport(sCsvExportHelper);
            csvExport.CreateSource<DummyClassTest>(d => d.Id);

            var dataList = new List<DummyClassTest>
                               {
                                    new DummyClassTest { Name = "Smith"},
                                    new DummyClassTest { Name = "George"}
                               };

            var csv = csvExport.Export(dataList);

            csv.Should().Not.Be.Null();
            csv.Result.Should().Not.Be.Null();
            csv.ToString().Should().Equal("Smith,\r\nGeorge,\r\n");
        }
    }
}
